package com.cf.game.cowboy.handler;

import com.cf.game.cowboy.CowBoyGame;
import com.cf.game.cowboy.GameStateDetail;
import com.cf.game.cowboy.handler.model.GameResult;
import com.cf.game.cowboy.handler.model.StakeItem;
import com.cf.game.cowboy.handler.model.UserStake;
import com.cf.game.service.service.UserInfoService;
import com.cf.game.service.service.h5game.H5GameInstanceService;
import com.cf.game.service.service.h5game.H5RoundGamePlayRecordService;
import com.cf.game.service.util.BeanFactoryUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.security.SecureRandom;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.cf.game.service.constants.EnumCoinReocrdType.XI_BU_DUI_JUE;

/**
 * cf-game-LotteryStrategy
 *
 * @author <a href="2428922347@qq.com">Zhu mingming</a>
 * @info
 * @since 2018/3/27 17:42
 */
@Component
public class LotteryStrategy {

    private Logger logger = LoggerFactory.getLogger(LotteryStrategy.class);

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private H5RoundGamePlayRecordService roundGamePlayRecordService;

    private SecureRandom csprng = new SecureRandom();

    public Integer getWinIndex(Integer num) {
        return csprng.nextInt(num);
    }

    @Transactional
    public GameResult getLotteryResult(CowBoyGame cowBoyGame) {
        GameStateDetail gameStateDetail = cowBoyGame.gameStateDetail;
        Map<String, List<StakeItem>> userStakes = gameStateDetail.getUserStakes();
        Integer winIndex = getWinIndex(6);
        Map<Integer, Double> winUsers = new HashMap<>();
        Double[] totalSend = {0D};
        getJkYhWinner(winIndex, userStakes.get(GameStateDetail.winGroup), winUsers, cowBoyGame, totalSend);
        getBulletWinner(winIndex, userStakes.get(GameStateDetail.bulletGroup), winUsers, cowBoyGame, totalSend);

        sendMnoey(winUsers, cowBoyGame.h5GameInstance.getId(), winIndex);
        GameResult gameResult = new GameResult(winIndex, winUsers, totalSend[0]);
        BeanFactoryUtil.getBean(H5GameInstanceService.class).updateGameInstanceResult(cowBoyGame.h5GameInstance.getId(), gameResult.getWinIndex(), gameResult.getTotalMoney());
        return gameResult;
    }


    private void sendMnoey(Map<Integer, Double> winUsers, String gameInstanceId, Integer winIndex) {

        if (winUsers != null && winUsers.size() > 0) {
            winUsers.forEach((userId, money) -> {
                logger.info("开始增加用户的金币【{}】【{}】", userId, money);
                roundGamePlayRecordService.updateWithPlaySuccess(gameInstanceId, userId, winIndex, winUsers.get(userId));
                //增加游戏币记录
                userInfoService.addUserCoinAmountAndSendMsg(userId, winUsers.get(userId).intValue(), XI_BU_DUI_JUE.getType(), "西部对决金币奖励", "小游戏获奖", "西部对决获奖金币" + winUsers.get(userId).intValue() + "已到账！");
            });
        }

    }

    private void getBulletWinner(Integer winIndex, List<StakeItem> stakeItems, Map<Integer, Double> winUsers, CowBoyGame cowBoyGame, Double[] totalSend) {
        StakeItem stakeItem = stakeItems.get(winIndex);
        logger.info("子弹中奖的用户：【{}】", stakeItem);
        createWinUser(winUsers, stakeItem, cowBoyGame, winIndex, totalSend);
    }

    private void getJkYhWinner(Integer winIndex, List<StakeItem> stakeItems, Map<Integer, Double> winUsers, CowBoyGame cowBoyGame, Double[] totalSend) {
        StakeItem stakeItem = stakeItems.get(winIndex % 2);
        logger.info("子弹中奖的用户：【{}】", stakeItem);
        createWinUser(winUsers, stakeItem, cowBoyGame, winIndex, totalSend);
    }

    private void createWinUser(Map<Integer, Double> winUsers, StakeItem stakeItem, CowBoyGame cowBoyGame, Integer winIndex, final Double[] totalSend) {
        if (stakeItem == null || stakeItem.getStakeMap() == null || stakeItem.getStakeMap().size() == 0)
            return;
        stakeItem.getStakeMap().forEach((Integer userId, UserStake userStake) -> {
            double send = userStake.getTotal() * stakeItem.getBei();
            totalSend[0] = totalSend[0] + send;
            Double beforeMoney = winUsers.get(userId);
            winUsers.put(userId, beforeMoney == null ? (0 + send) : (beforeMoney + send));
        });
    }


}
